package rc.work.module.infra.service.onlyoffice;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jodd.util.StringUtil;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import rc.work.framework.common.util.io.FileUtils;
import rc.work.framework.security.core.LoginUser;
import rc.work.framework.security.core.util.SecurityFrameworkUtils;

import rc.work.module.infra.api.file.FileApi;

import rc.work.module.infra.api.file.dto.FileCreateReqDTO;
import rc.work.module.infra.dal.dataobject.file.FileDO;
import rc.work.module.infra.dal.mysql.file.FileMapper;
import rc.work.module.infra.dal.mysql.onlyoffice.OfficeHistoryMapper;
import rc.work.module.infra.framework.file.core.client.FileClient;
import rc.work.module.infra.framework.file.core.utils.FileTypeUtils;
import rc.work.module.infra.service.file.FileConfigService;
import rc.work.module.infra.util.DateUtil;

import java.io.InputStream;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * onlyoffice Service 实现类
 *
 * @author 默认
 */
@Service
@Validated
public class OnlyOfficeServiceImpl implements OnlyOfficeService {

    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private FileApi fileApi;

    @Value("${onlyoffice.docservice.callbackUrl}")
    private String callbackUrl;

    @Autowired
    private OfficeHistoryMapper officeHistoryMapper;

//    @Autowired
//    private ZhfxypBgInfoMapper zhfxypBgInfoMapper;




    @Override
    public String save(Long fileId, String fileType,Long userId, String userName, HttpServletRequest request, HttpServletResponse response) {
        try {
//            LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
            Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
            String body = scanner.hasNext() ? scanner.next() : "";
            scanner.close();

            JSONObject jsonObj = JSONObject.parseObject(body);
           // System.out.println("jsonObj============" + jsonObj);
            long status = 0;
            if(jsonObj.get("status")!=null &&StringUtil.isNotBlank(String.valueOf(jsonObj.get("status")))){
                status=Long.parseLong(String.valueOf(jsonObj.get("status")));
            }
//            if (status == 2 || status == 3 || status == 6) {
            if (status == 6) {
                String downloadUri = (String) jsonObj.get("url");
                System.out.println("downloadUri============" + downloadUri);
                URL url = new URL(downloadUri);
                java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
                InputStream stream = connection.getInputStream();
                Map<String, Object> map = new HashMap<>();
                map.put("report_id", fileId);
                FileDO fileTableDO = fileMapper.selectById(fileId);

//                int bbh = officeHistoryMapper.selectCountByFileId(String.valueOf(fileId));
//                int serverversion=bbh+1;


                String filename = fileTableDO.getName();
                String fileurl = fileTableDO.getUrl();
                String path = fileTableDO.getPath();
                byte[] bytes = IOUtils.toByteArray(stream);
                FileCreateReqDTO dto = new FileCreateReqDTO();
                dto.setName(filename).setDirectory(path).setContent(bytes);
                //CommonResult<String> urlresult = fileApi.createFile(dto);

                String fileurlnew = createFile(dto.getName(), dto.getDirectory(),
                        dto.getContent());

                String urlnew=fileurlnew;

                fileTableDO.setPath(path);
                fileTableDO.setUrl(urlnew);
                fileMapper.updateById(fileTableDO);
//                if("dev_zhfxyp_bg_info".equals(fileTableDO.getTableName()) && "bg".equals(fileTableDO.getTableType())){
//                    Long bgid = fileTableDO.getTableId();
//                    ZhfxypBgInfoDO bgInfoDO=zhfxypBgInfoMapper.selectById(bgid);
//                    bgInfoDO.setBgUrl(urlnew);
//                    bgInfoDO.setFileId(fileTableDO.getId());
//                    zhfxypBgInfoMapper.updateById(bgInfoDO);
//                }
//
//
//                String filesuffix=filename.substring(filename.lastIndexOf(".")+1);
//                OfficeHistoryDO historyDO=new OfficeHistoryDO().setFileName(fileTableDO.getName())
//                        .setFileUrl(urlnew).setFilePath(path).setUserId(userId).setCreator(userName)
//                        .setServerVersion(String.valueOf(serverversion))
//                        .setFileId(String.valueOf(fileId)).setTableName(fileType).setFileSuffix(filesuffix)
//                        .setDocKey(fileType+ fileId+ DateUtil.formatDate(new Date(),"yyMMddhh")+serverversion)                        ;
//
//                officeHistoryMapper.insert(historyDO);

//                List<ReportFile> reportFiles = reportFileMapper.selectByMap(map);
//                log.info(" 查询到的报告信息: {}", reportFiles);
//                if (!CollectionUtils.isEmpty(reportFiles)) {
//                    ReportFile reportFile = reportFiles.get(0);
//                    File savedFile = new File(upLoadPath + "/" + reportFile.getFilePath());
//                    try (FileOutputStream out = new FileOutputStream(savedFile)) {
//                        int read;
//                        final byte[] bytes = new byte[1024];
//                        while ((read = stream.read(bytes)) != -1) {
//                            out.write(bytes, 0, read);
//                        }
//                        out.flush();
//                    }
//                    connection.disconnect();
//                }

            }
        } catch (Exception e) {
            e.printStackTrace();
            return "{\"error\":1}";
        }
        return "{\"error\":0}";
    }
    @jakarta.annotation.Resource
    private FileConfigService fileConfigService;
    public String createFile(String name, String path, byte[] content) throws Exception {
        // 计算默认的 path 名
        String type = FileTypeUtils.getMineType(content, name);
        if (StrUtil.isEmpty(path)) {
            path = FileUtils.generatePath(content, name);
        }
        // 如果 name 为空，则使用 path 填充
        if (StrUtil.isEmpty(name)) {
            name = path;
        }

        // 上传到文件存储器
        FileClient client = fileConfigService.getMasterFileClient();
        Assert.notNull(client, "客户端(master) 不能为空");
        String url = client.upload(content, path, type);

        // 保存到数据库
        FileDO file = new FileDO();
        file.setConfigId(client.getId());
        file.setName(name);
        file.setPath(path);
        file.setUrl(url);
        file.setType(type);
        file.setSize(content.length);
        fileMapper.insert(file);
        return url;
    }
    @Override
    public Map<String, Object> createConfig(Long fileId, String fileType, HttpServletRequest request) {
        Map<String, Object> configMap = new HashMap<>();
        Map<String, Object> document = new HashMap<>();
        Map<String, Object> map = new HashMap<>();

        // 获取当前登录用户
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        // 根据文件ID查询文件信息
        FileDO fileTableDO = fileMapper.selectById(fileId);
       // int bbh = officeHistoryMapper.selectCountByFileId(String.valueOf(fileId));

        // 获取文件扩展名
        String fileName = fileTableDO.getName();
        String fileExtension = getFileExtension(fileName);

        if (fileExtension == null) {
            // 如果文件没有有效的扩展名，返回错误
            configMap.put("error", "无效的文件扩展名");
            return configMap;
        }

        document.put("fileType", fileExtension);
        document.put("title", fileName);
        String key = fileId + "_" + System.currentTimeMillis();
        document.put("key", key);
        document.put("url", fileTableDO.getUrl());

        // 设置文件类型（word 或 cell）
        if (fileExtension.equalsIgnoreCase("doc") || fileExtension.equalsIgnoreCase("docx")) {
            configMap.put("documentType", "word");
        } else if (fileExtension.equalsIgnoreCase("xls") || fileExtension.equalsIgnoreCase("xlsx")) {
            configMap.put("documentType", "cell");
        }

        configMap.put("document", document);

        // 设置编辑器配置
        Map<String, Object> editorConfig = new HashMap<>();
        String cbUrl = callbackUrl + "?fileId=" + fileId + "&fileType=" + fileExtension + "&userId=" + loginUser.getId() + "&userName=" + loginUser.getInfo().get("nickname");
        editorConfig.put("callbackUrl", cbUrl);
        editorConfig.put("lang", "zh-CN");
        editorConfig.put("mode", "edit");

        // 用户信息
        Map<String, Object> user = new HashMap<>();
        user.put("id", loginUser.getId());
        user.put("name", loginUser.getInfo().get("nickname"));
        editorConfig.put("user", user);

        // 自定义设置
        Map<String, Object> customization = new HashMap<>();
        customization.put("autosave", Boolean.TRUE);
        customization.put("forcesave", Boolean.TRUE);
        customization.put("chat", Boolean.FALSE);
        customization.put("commentAuthorOnly", Boolean.FALSE);
        customization.put("comments", Boolean.FALSE);
        customization.put("compactHeader", Boolean.FALSE);
        customization.put("compactToolbar", Boolean.FALSE);
        customization.put("compatibleFeatures", Boolean.FALSE);
        customization.put("macros", Boolean.FALSE);
        customization.put("macrosMode", "warn");
        customization.put("plugins", Boolean.FALSE);
        customization.put("showReviewChanges", Boolean.FALSE);
        customization.put("spellcheck", Boolean.FALSE);
        customization.put("toolbarNoTabs", Boolean.FALSE);

        editorConfig.put("customization", customization);
        configMap.put("editorConfig", editorConfig);
        configMap.put("height", "100%");
        configMap.put("width", "100%");
        configMap.put("type", "desktop");

        return configMap;
    }

    // 获取文件扩展名的辅助方法
    private String getFileExtension(String fileName) {
        if (fileName == null || fileName.isEmpty()) {
            return null;
        }
        int dotIndex = fileName.lastIndexOf('.');
        if (dotIndex == -1 || dotIndex == fileName.length() - 1) {
            return null;
        }
        return fileName.substring(dotIndex + 1).toLowerCase();
    }

//    public Map<String, Object> createConfig(Long fileId, String fileType, HttpServletRequest request) {
//        Map<String, Object> configMap = new HashMap<>();
//        Map<String ,Object> document = new HashMap<>();
//        Map<String, Object> map = new HashMap<>();
////
////        map.put("report_id", fileId);
////        List<ReportFile> reportFiles = reportFileMapper.selectByMap(map);
////        if (CollectionUtils.isEmpty(reportFiles)) {
////            return configMap;
////        }
////        ReportFile reportFile = reportFiles.get(0);
////        document.put("fileType","docx");
////        document.put("title",reportFile.getFileName());
////        document.put("key", fileId+ DateUtil.formatDate(new Date(),"yyMMdd"));
////        String fileUrl = resUrl+reportFile.getFilePath();
////        String cbUrl = callbackUrl+"?caseId="+caseId+"&fileId="+fileId;
//        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
//        FileDO fileTableDO = fileMapper.selectById(fileId);
//        int bbh = officeHistoryMapper.selectCountByFileId(String.valueOf(fileId));
//
//        String filetype = fileTableDO.getName();
//        filetype=filetype.substring(filetype.lastIndexOf(".")+1);
//        document.put("fileType",filetype);
//        document.put("title",fileTableDO.getName());
//        //document.put("key",fileType+ fileId+ DateUtil.formatDate(new Date(),"yyMMdd")+bbh);
//        document.put("key","VYTXefAD36cd2Q6AFCZFqDcu7SBsNllb");
//        document.put("url",fileTableDO.getUrl());
//        configMap.put("document",document);
//        configMap.put("documentType","word");
//        Map<String ,Object> editorConfig = new HashMap<>();
//        String cbUrl = callbackUrl+"?fileId="+fileId+"&fileType="+fileType+"&userId="+loginUser.getId()+"&userName="+loginUser.getInfo().get("nickname");
//        editorConfig.put("callbackUrl",cbUrl);
//
//
//        editorConfig.put("lang","zh-CN");
//        editorConfig.put("mode","edit");
//        Map<String ,Object> user = new HashMap<>();
//        user.put("id",loginUser.getId());
//        user.put("name",loginUser.getInfo().get("nickname"));
//        editorConfig.put("user",user);
//        Map<String ,Object> customization = new HashMap<>();
//        customization.put("autosave",Boolean.TRUE);
//        customization.put("forcesave",Boolean.TRUE);
//        customization.put("chat",Boolean.FALSE);
//        customization.put("commentAuthorOnly",Boolean.FALSE);
//        customization.put("comments",Boolean.FALSE);
//        customization.put("compactHeader",Boolean.FALSE);
//        customization.put("compactToolbar",Boolean.FALSE);
//        customization.put("compatibleFeatures",Boolean.FALSE);
//        customization.put("macros",Boolean.FALSE);
//        customization.put("macrosMode","warn");
//        customization.put("plugins",Boolean.FALSE);
//        customization.put("showReviewChanges",Boolean.FALSE);
//        customization.put("spellcheck",Boolean.FALSE);
//        customization.put("toolbarNoTabs",Boolean.FALSE);
//        editorConfig.put("customization",customization);
//        configMap.put("editorConfig",editorConfig);
//        configMap.put("height","100%");
//        configMap.put("width","100%");
//        configMap.put("type","desktop");
//        return configMap;
//    }

    @Override
    public ResponseEntity<Resource> getFile(Long fileId, String fileType) {
        try {
            FileDO reportFile = fileMapper.selectById(fileId);
            Path filePath = Paths.get(reportFile.getUrl());
            Resource resource = new UrlResource(filePath.toUri());
            String contentType = "application/octet-stream";
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .header(HttpHeaders.CONTENT_DISPOSITION,
                            "attachment; filename=\""+reportFile.getName()+"\"")
                    .body(resource);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public String saveNew(Long fileId, String fileType,Long userId, String userName, HttpServletRequest request, HttpServletResponse response) {
//        try {
////            LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
//            Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
//            String body = scanner.hasNext() ? scanner.next() : "";
//            scanner.close();
//
//            JSONObject jsonObj = JSONObject.parseObject(body);
//            System.out.println("jsonObj============" + jsonObj);
//            long status = 0;
//            if(jsonObj.get("status")!=null &&StringUtil.isNotBlank(String.valueOf(jsonObj.get("status")))){
//                status=Long.parseLong(String.valueOf(jsonObj.get("status")));
//            }
////            if (status == 2 || status == 3 || status == 6) {
//            if (status == 6) {
//                String downloadUri = (String) jsonObj.get("url");
//                System.out.println("downloadUri============" + downloadUri);
//                URL url = new URL(downloadUri);
//                java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
//                InputStream stream = connection.getInputStream();
//                Map<String, Object> map = new HashMap<>();
//                map.put("report_id", fileId);
//                FileInfoDo fileTableDO = fileMapper.getFileInfoDo(fileId);
//
//                int bbh = officeHistoryMapper.selectCountByFileId(String.valueOf(fileId));
//                int serverversion=bbh+1;
//
//
//                String filename = fileTableDO.getName();
//                String fileurl = fileTableDO.getUrl();
//                String path = fileTableDO.getPath();
//                byte[] bytes = IOUtils.toByteArray(stream);
//
//                String urlnew=fileApi.createFile(filename,serverversion+path,bytes);
//
//                fileTableDO.setPath(serverversion+path);
//                fileTableDO.setUrl(urlnew);
//                fileMapper.updateFileInfoDo(fileTableDO);
//
//
////                String filesuffix=filename.substring(filename.lastIndexOf(".")+1);
////                OfficeHistoryDO historyDO=new OfficeHistoryDO().setFileName(fileTableDO.getName())
////                        .setFileUrl(urlnew).setFilePath(path).setUserId(userId).setCreator(userName)
////                        .setServerVersion(String.valueOf(serverversion))
////                        .setFileId(String.valueOf(fileId)).setTableName(fileType).setFileSuffix(filesuffix)
////                        .setDocKey(fileType+ fileId+ DateUtil.formatDate(new Date(),"yyMMddhh")+serverversion)                        ;
////
////                officeHistoryMapper.insert(historyDO);
//
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            return "{\"error\":1}";
//        }
        return "{\"error\":0}";
    }

    @Override
    public Map<String, Object> createConfigNew(Long fileId, String fileType, HttpServletRequest request) {
        Map<String, Object> configMap = new HashMap<>();
        Map<String ,Object> document = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        //FileInfoDo fileTableDO = fileMapper.getFileInfoDo(fileId);
        FileDO fileTableDO = fileMapper.selectById(fileId);
        int bbh = officeHistoryMapper.selectCountByFileId(String.valueOf(fileId));

        String filetype = fileTableDO.getName();
        filetype=filetype.substring(filetype.lastIndexOf(".")+1);
        document.put("fileType",filetype);
        document.put("title",fileTableDO.getName());
        document.put("key",fileType+ fileId+ DateUtil.formatDate(new Date(),"yyMMdd")+bbh);
        document.put("url",fileTableDO.getUrl());
        configMap.put("document",document);
        configMap.put("documentType","word");
        Map<String ,Object> editorConfig = new HashMap<>();
        String cbUrl = callbackUrl+"?fileId="+fileId+"&fileType="+fileType+"&userId="+loginUser.getId()+"&userName="+loginUser.getInfo().get("nickname");
        editorConfig.put("callbackUrl",cbUrl);


        editorConfig.put("lang","zh-CN");
        editorConfig.put("mode","edit");
        Map<String ,Object> user = new HashMap<>();
        user.put("id",loginUser.getId());
        user.put("name",loginUser.getInfo().get("nickname"));
        editorConfig.put("user",user);
        Map<String ,Object> customization = new HashMap<>();
        customization.put("autosave",Boolean.TRUE);
        customization.put("forcesave",Boolean.TRUE);
        customization.put("chat",Boolean.FALSE);
        customization.put("commentAuthorOnly",Boolean.FALSE);
        customization.put("comments",Boolean.FALSE);
        customization.put("compactHeader",Boolean.FALSE);
        customization.put("compactToolbar",Boolean.FALSE);
        customization.put("compatibleFeatures",Boolean.FALSE);
        customization.put("macros",Boolean.FALSE);
        customization.put("macrosMode","warn");
        customization.put("plugins",Boolean.FALSE);
        customization.put("showReviewChanges",Boolean.FALSE);
        customization.put("spellcheck",Boolean.FALSE);
        customization.put("toolbarNoTabs",Boolean.FALSE);
        editorConfig.put("customization",customization);
        configMap.put("editorConfig",editorConfig);
        configMap.put("height","100%");
        configMap.put("width","100%");
        configMap.put("type","desktop");
        return configMap;
    }

    @Override
    public ResponseEntity<Resource> getFileNew(Long fileId, String fileType) {
        try {
            //FileInfoDo reportFile = fileMapper.getFileInfoDo(fileId);
            FileDO reportFile = fileMapper.selectById(fileId);
            Path filePath = Paths.get(reportFile.getUrl());
            Resource resource = new UrlResource(filePath.toUri());
            String contentType = "application/octet-stream";
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .header(HttpHeaders.CONTENT_DISPOSITION,
                            "attachment; filename=\""+reportFile.getName()+"\"")
                    .body(resource);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}